package com.example.picturestorage.aop;

import com.example.picturestorage.bean.TypeAndMethod;
import com.example.picturestorage.controller.PublisherController;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {

    private final static Logger LOGGER = LoggerFactory.getLogger(MyAspect.class);
    
    @Autowired
    private TypeAndMethod typeAndMethod;

//    ThreadLocal<TypeAndMethod> threadLocal;

    @Pointcut("execution(* com.example.picturestorage.test..*.*(..))")
//    @Pointcut("execution(* com.example.picturestorage.controller..*.*(..))")
    public void pointCut(){

    }

    int i=0;
    @Before("pointCut()")
    public TypeAndMethod doBefore(JoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        String declaringTypeName = signature.getDeclaringTypeName();
        String name = signature.getName();
        LOGGER.info("类名:"+declaringTypeName+" 方法:"+name);
        ThreadLocal<String> type = new ThreadLocal<>();
        type.set(declaringTypeName);
        ThreadLocal<String> method = new ThreadLocal<>();
        method.set(name);
        typeAndMethod.setMethod(method);
        typeAndMethod.setType(type);
        typeAndMethod.setMethod2(name);
        typeAndMethod.setType2(declaringTypeName);
        LOGGER.info("AOP Before Advice..."+i++);
        return typeAndMethod;
    }

    @After("pointCut()")
    public void doAfter(JoinPoint joinPoint){
        LOGGER.info("AOP After Advice..."+i++);
    }

    @AfterReturning(pointcut="pointCut()",returning="returnVal")
    public void afterReturn(JoinPoint joinPoint,Object returnVal){
//        Signature signature = joinPoint.getSignature();
//        String declaringTypeName = signature.getDeclaringTypeName();
//        String name = signature.getName();
//        LOGGER.info("类名:"+declaringTypeName+" 方法:"+name);
        LOGGER.info("AOP AfterReturning Advice:" + returnVal);
    }

    @AfterThrowing(pointcut="pointCut()",throwing="error")
    public void afterThrowing(JoinPoint joinPoint,Throwable error){
        LOGGER.info("AOP AfterThrowing Advice..." + error);
        LOGGER.info("AfterThrowing...");
    }

//    @Around("pointCut()")
//    public Object around(ProceedingJoinPoint pjp){
//        LOGGER.info("AOP Around before...");
//        try {
//            pjp.proceed();
//        } catch (Throwable e) {
//            e.printStackTrace();
//        }
//        LOGGER.info("AOP Around after...");
//        return null;
//    }
}
